package cn.jh.smartos.client;

import android.app.Service;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.os.RemoteException;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.ref.WeakReference;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Arrays;
import java.util.List;

import cn.jh.smartos.IBackService;
import cn.jh.smartos.utils.ToastU;

/**
 * Created by pjh on 18/3/12.
 */

public class ClientService extends Service {
    private static final String TAG = "ClientService";
    /**
     * 心跳频率
     */
    private static final long HEART_BEAT_RATE = 3 * 1000;
    /**
     * 服务器ip地址
     */
    public String HOST = "192.168.123.27";// "192.168.1.21";//
    /**
     * 服务器端口号
     */
    public int PORT = 9800;

    public static final String CLIENT_ACTION = "android.intent.action.jh.smartos.client_service";
    /**
     * 服务器消息回复广播
     */
    public static final String CONNECT_STATE = "connect_state";

    /**
     * 服务器消息回复广播
     */
    public static final String MESSAGE_ACTION = "message_action";

    public static final String MESSAGE_USER = "message_user";
    /**
     * 服务器心跳回复广播
     */
    public static final String HEART_BEAT_ACTION = "heart_beat_action";
    /**
     * 读线程
     */
    private ReadThread mReadThread;

    private LocalBroadcastManager mLocalBroadcastManager;
    /***/
    private WeakReference<Socket> mSocket;

    // For heart Beat
    private Handler mHandler = new Handler();
    /**
     * 心跳任务，不断重复调用自己
     */
    private Runnable heartBeatRunnable = new Runnable() {

        @Override
        public void run() {
            if (System.currentTimeMillis() - sendTime >= HEART_BEAT_RATE) {
                boolean isSuccess = sendMsg("HeartBeat");//就发送一个\r\n过去 如果发送失败，就重新初始化一个socket
                if (!isSuccess) {
                    mHandler.removeCallbacks(heartBeatRunnable);
                    mReadThread.release();
                    releaseLastSocket(mSocket);
                    new InitSocketThread().start();
                } else {
//                    Log.e(TAG,"HeartBeat --> 心跳发送成功");
                }
            }
            mHandler.postDelayed(this, HEART_BEAT_RATE);
        }
    };


    private long sendTime = 0L;
    /**
     * aidl通讯回调
     */
    private IBackService.Stub iBackService = new IBackService.Stub() {

        /**
         * 收到内容发送消息
         * @param message 需要发送到服务器的消息
         * @return
         * @throws RemoteException
         */
        @Override
        public boolean sendMessage(String message) throws RemoteException {
            return sendMsg(message);
        }
    };

    @Override
    public IBinder onBind(Intent arg0) {
        return iBackService;
    }

    @Override
    public void onCreate() {
        super.onCreate();

        mLocalBroadcastManager = LocalBroadcastManager.getInstance(this);

    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.e(TAG, "---------");
        try {
            String mac = intent.getStringExtra("mac");
            String port = intent.getStringExtra("port");
            int int_port = Integer.parseInt(port);
            PORT = int_port;
            HOST = mac;

            new InitSocketThread().start();

        } catch (Exception e) {
            e.printStackTrace();
            Log.e(TAG, e.getMessage());
        }

        return super.onStartCommand(intent, flags, startId);
    }

    public boolean sendMsg(final String msg) {
        if (null == mSocket || null == mSocket.get()) {
            return false;
        }
        final Socket soc = mSocket.get();
        if (!soc.isClosed() && !soc.isOutputShutdown()) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        OutputStream os = soc.getOutputStream();
                        String message = "["+soc.getLocalSocketAddress()+"]:"+msg + "\r\n";
                        os.write(message.getBytes());
                        os.flush();


                            Log.e(TAG, message);

                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }).start();
            sendTime = System.currentTimeMillis();//每次发送成数据，就改一下最后成功发送的时间，节省心跳间隔时间
        } else {
            return false;
        }
        return true;
    }

    private void initSocket() {//初始化Socket
        try {

            Socket so = new Socket(HOST, PORT);

            mSocket = new WeakReference<Socket>(so);
            mReadThread = new ReadThread(so);
            mReadThread.start();
            mHandler.postDelayed(heartBeatRunnable, HEART_BEAT_RATE);//初始化成功后，就准备发送心跳包
            Log.e(TAG, "初始化成功:" + so.getInetAddress());

            Intent intent = new Intent(CONNECT_STATE);
            intent.putExtra(CONNECT_STATE, true);
            intent.putExtra("ip", HOST);
            intent.putExtra("port", "" + PORT);
            mLocalBroadcastManager.sendBroadcast(intent);

        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 心跳机制判断出socket已经断开后，就销毁连接方便重新创建连接
     *
     * @param mSocket
     */
    private void releaseLastSocket(WeakReference<Socket> mSocket) {
        try {
            if (null != mSocket) {
                Socket sk = mSocket.get();
                if (!sk.isClosed()) {
                    sk.close();
                }
                sk = null;
                mSocket = null;
                Log.e(TAG, "releaseLastSocket");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    class InitSocketThread extends Thread {
        @Override
        public void run() {
            super.run();
            initSocket();
        }
    }

    // Thread to read content from Socket
    class ReadThread extends Thread {
        private WeakReference<Socket> mWeakSocket;
        private boolean isStart = true;

        public ReadThread(Socket socket) {
            mWeakSocket = new WeakReference<Socket>(socket);
        }

        public void release() {
            isStart = false;
            releaseLastSocket(mWeakSocket);
        }

        @Override
        public void run() {
            super.run();
            Socket socket = mWeakSocket.get();
            if (null != socket) {
                try {
                    InputStream is = socket.getInputStream();
                    byte[] buffer = new byte[1024 * 4];
                    int length = 0;
                    while (!socket.isClosed() && !socket.isInputShutdown()
                            && isStart && ((length = is.read(buffer)) != -1)) {
                        if (length > 0) {
                            String message = new String(Arrays.copyOf(buffer,
                                    length)).trim();
                            try {
                                String[] list = message.split("]:");
                                String ip = list[0].substring(2);
                                String msg=list[list.length-1].substring(0);
                                Log.e(TAG, "客户端解析："+ip+",msg = "+msg);
                                //收到服务器过来的消息，就通过Broadcast发送出去
                                if (msg.equals("ACK:HeartBeat")) {//处理心跳回复
                                    Intent intent = new Intent(HEART_BEAT_ACTION);
                                    mLocalBroadcastManager.sendBroadcast(intent);
                                } else {
                                    //其他消息回复
                                    if (msg.equals("ACK:connect_close")) {
//                                    ToastU.INSTANCE.showToast("ACK:connect_close");
                                        stopSelf();
                                    } else {
                                        Intent intent = new Intent(MESSAGE_ACTION);
                                        intent.putExtra(MESSAGE_USER,ip);
                                        intent.putExtra(MESSAGE_ACTION, msg);
                                        Log.e(TAG, "收到"+ip+" : " + msg);
                                        mLocalBroadcastManager.sendBroadcast(intent);
                                    }

                                }
                            }catch (Exception e){
                                e.printStackTrace();
                            }


                        }
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        mHandler.removeCallbacks(heartBeatRunnable);
        mReadThread.release();
        releaseLastSocket(mSocket);
        ToastU.INSTANCE.showToast("关闭服务器");
    }
}
